﻿using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Reflection;

namespace SystemUpdatesCore.Server.Network
{
    /// <summary>
    /// 下载进度更改的事件参数
    /// </summary>
    public class NetworkDownloadProgressChangedEventArgs : ProgressChangedEventArgs
    {
        internal NetworkDownloadProgressChangedEventArgs(int progressPercentage, object? userToken, long bytesReceived, long totalBytesToReceive) :
            base(progressPercentage, userToken)
        {
            BytesReceived = bytesReceived;
            TotalBytesToReceive = totalBytesToReceive;
        }


        /// <summary>
        /// 已下载的字节
        /// </summary>
        public long BytesReceived { get; }

        /// <summary>
        /// 总文件字节
        /// </summary>
        public long TotalBytesToReceive { get; }

    }

    /// <summary>
    /// 下载string完成
    /// </summary>
    public class NetworkDownloadStringCompletedEventArgs : AsyncCompletedEventArgs
    {
        private readonly string? _result;

        internal NetworkDownloadStringCompletedEventArgs(string? result, Exception? exception, bool cancelled, object? userToken) : base(exception, cancelled, userToken)
        {
            _result = result;
        }

        public string Result
        {
            get
            {
                RaiseExceptionIfNecessary();
                return _result!;
            }
        }

    }




    //
    // 摘要:
    //     Represents the method that will handle the System.Net.WebClient.DownloadProgressChanged
    //     event of a System.Net.WebClient.
    //
    // 参数:
    //   sender:
    //     The source of the event.
    //
    //   e:
    //     A System.Net.DownloadProgressChangedEventArgs containing event data.
    public delegate void NetworkDownloadProgressChangedEventHandler(object sender, NetworkDownloadProgressChangedEventArgs e);


    //
    // 摘要:
    //     Represents the method that will handle the System.Net.WebClient.DownloadStringCompleted
    //     event of a System.Net.WebClient.
    //
    // 参数:
    //   sender:
    //     The source of the event.
    //
    //   e:
    //     A System.Net.DownloadStringCompletedEventArgs that contains event data.
    public delegate void NetworkDownloadStringCompletedEventHandler(object sender, NetworkDownloadStringCompletedEventArgs e);



    /// <summary>
    /// 下载文件完成
    /// </summary>
    public class NetworkAsyncCompletedEventArgs : EventArgs
    {
        public NetworkAsyncCompletedEventArgs(Exception? error, bool cancelled, object? userState)
        {
            Cancelled = cancelled;
            Error = error;
            UserState = userState;
        }

        public NetworkAsyncCompletedEventArgs(int downloadNum, int totalDownloadNum, Exception? error, bool cancelled, object? userState, UpdateFileModel? downloadFile=null   )
        {
            DownloadNum = downloadNum;
            TotalDownloadNum = totalDownloadNum;

            Cancelled = cancelled;
            Error = error;
            UserState = userState;

            DownloadFile = downloadFile;
        }

        protected void RaiseExceptionIfNecessary()
        {
            if (Error != null)
            {
                throw new TargetInvocationException(Error);
            }
            else if (Cancelled)
            {
                throw new InvalidOperationException(Error.Message);
            }
        }

        public bool Cancelled { get; }
        public Exception? Error { get; }
        public object? UserState { get; }

        /// <summary>
        /// 已下载数
        /// </summary>
        public int DownloadNum { get; }
        /// <summary>
        /// 需要下载数
        /// </summary>
        public int TotalDownloadNum { get; }
        /// <summary>
        /// 全部下载完成
        /// </summary>
        public bool DownloadAll { get { return DownloadNum == TotalDownloadNum; } }

        /// <summary>
        /// 下载完成的文件
        /// </summary>
        public UpdateFileModel? DownloadFile { get; }



    }

    //
    // 摘要:
    //     Represents the method that will handle the MethodNameCompleted event of an asynchronous
    //     operation.
    //
    // 参数:
    //   sender:
    //     The source of the event.
    //
    //   e:
    //     An System.ComponentModel.AsyncCompletedEventArgs that contains the event data.
    public delegate void NetworkAsyncCompletedEventHandler(object? sender, NetworkAsyncCompletedEventArgs e);




    public interface INetworkClient
    {
        [AllowNull]
        string BaseAddress { get; set; }

        /// <summary>
        /// 异步下载文件完成事件
        /// </summary>
        event AsyncCompletedEventHandler? DownloadFileCompleted;
        /// <summary>
        /// 异步下载文件进度改变事件
        /// </summary>
        event NetworkDownloadProgressChangedEventHandler? DownloadProgressChanged;

        /// <summary>
        /// 异步获取字符串完成事件
        /// </summary>
        event NetworkDownloadStringCompletedEventHandler? DownloadStringCompleted;


        Task DownloadFileTaskAsync(string address, string fileName);

        /// <summary>
        /// 异步下载文件
        /// </summary>
        /// <param name="address"></param>
        /// <param name="fileName"></param>
        void DownloadFileAsync(Uri address, string fileName);

        /// <summary>
        /// 同步下载文件
        /// </summary>
        /// <param name="address"></param>
        /// <param name="fileName"></param>
        void DownloadFile(string address, string fileName);

        Task<string> DownloadStringTaskAsync(string address);

        /// <summary>
        /// 异步获取字符串数据
        /// </summary>
        /// <param name="address"></param>
        void DownloadStringAsync(Uri address);

        /// <summary>
        /// 同步获取字符串数据
        /// </summary>
        /// <param name="address"></param>
        string DownloadString(string address);

    }
}